﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;


using RaisingStudio.SmallProgram.Library.Internal;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media;

namespace RaisingStudio.SmallProgram.Library
{
    [SmallProgramType]
    public static class Sound
    {
        private static Dictionary<Uri, MediaElement> _mediaPlayerMap = new Dictionary<Uri, MediaElement>();

        private static MediaElement GetMediaPlayer(Primitive filePath)
        {
            if (!filePath.IsEmpty)
            {
                try
                {
                    MediaElement mediaPlayer;
                    Uri key = new Uri((string)filePath);
                    if (!_mediaPlayerMap.TryGetValue(key, out mediaPlayer))
                    {
                        mediaPlayer = new MediaElement();
                        _mediaPlayerMap[key] = mediaPlayer;
                        mediaPlayer.AutoPlay = false;
                        mediaPlayer.Source = key;
                    }
                    if (!GraphicsWindow._container.Children.Contains(mediaPlayer))
                    {
                        GraphicsWindow._container.Children.Add(mediaPlayer);
                        mediaPlayer.MediaEnded += delegate
                            {
                                GraphicsWindow._container.Children.Remove(mediaPlayer);
                            };
                    }
                    return mediaPlayer;
                }
                catch (Exception exception)
                {
                    Debug.WriteLine(exception.ToString());
                }
            }
            return null;
        }

        public static void Pause(Primitive filePath)
        {
            SmallProgramApplication.BeginInvoke(delegate
            {
                MediaElement mediaPlayer = GetMediaPlayer(filePath);
                if (mediaPlayer != null)
                {
                    mediaPlayer.Pause();
                }
            });
        }

        public static void Play(Primitive filePath)
        {
            SmallProgramApplication.BeginInvoke(delegate
            {
                MediaElement mediaPlayer = GetMediaPlayer(filePath);
                if (mediaPlayer != null)
                {
                    if (mediaPlayer.CurrentState == MediaElementState.Stopped)
                    {
                        mediaPlayer.Play();
                    }
                    else
                    {
                        mediaPlayer.MediaOpened += delegate
                            {
                                mediaPlayer.Play();
                            };
                    }
                }
            });
        }

        public static void PlayAndWait(Primitive filePath)
        {
            SmallProgramApplication.Invoke(delegate
            {
                MediaElement mediaPlayer = GetMediaPlayer(filePath);
                if (mediaPlayer != null)
                {
                    AutoResetEvent autoResetEvent = new AutoResetEvent(false);
                    mediaPlayer.Play();
                    for (int j = 0; !autoResetEvent.WaitOne(200); j++)
                    {
                        if ((j > 30) && (mediaPlayer.Position == TimeSpan.Zero))
                        {
                            autoResetEvent.Set();
                        }
                        if (mediaPlayer.NaturalDuration.Type == Windows.UI.Xaml.DurationType.TimeSpan && (mediaPlayer.Position >= mediaPlayer.NaturalDuration.TimeSpan))
                        {
                            autoResetEvent.Set();
                        }
                    }
                    mediaPlayer.Stop();
                }
            });
        }

        public static void PlayBellRing()
        {
            PlayStockSound("BellRing.mp3", false);
        }

        public static void PlayBellRingAndWait()
        {
            PlayStockSound("BellRing.mp3", true);
        }

        public static void PlayChime()
        {
            PlayStockSound("Chime.mp3", false);
        }

        public static void PlayChimeAndWait()
        {
            PlayStockSound("Chime.mp3", true);
        }

        public static void PlayChimes()
        {
            PlayStockSound("Pause.mp3", false);
        }

        public static void PlayChimesAndWait()
        {
            PlayStockSound("Pause.mp3", true);
        }

        public static void PlayClick()
        {
            PlayStockSound("Click.mp3", false);
        }

        public static void PlayClickAndWait()
        {
            PlayStockSound("Click.mp3", true);
        }

        public static void PlayMusic(Primitive music)
        {
        }

        private static void PlayStockSound(string name, bool sync)
        {
            SmallProgramApplication.Invoke(delegate
            {
                MediaElement player = new MediaElement
                {
                    AutoPlay = false,
                    Source = new Uri("Sounds/" + name, UriKind.RelativeOrAbsolute)
                };
                GraphicsWindow._container.Children.Add(player);
                player.MediaOpened += delegate
                {
                    player.Play();
                };
                player.MediaEnded += delegate
                {
                    GraphicsWindow._container.Children.Remove(player);
                };
            });
        }

        public static void Stop(Primitive filePath)
        {
            SmallProgramApplication.BeginInvoke(delegate
            {
                MediaElement mediaPlayer = GetMediaPlayer(filePath);
                if (mediaPlayer != null)
                {
                    mediaPlayer.Stop();
                }
            });
        }
    }
}

